package com.cool.shark.service.Impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.cool.shark.ex.ServiceException;
import com.cool.shark.mapper.BannerMapper;
import com.cool.shark.pojo.dto.BannerDTO;
import com.cool.shark.pojo.entity.Banner;
import com.cool.shark.pojo.vo.BannerStandardVO;
import com.cool.shark.pojo.vo.BannerVO;
import com.cool.shark.service.BannerService;
import com.cool.shark.utils.UploadGiteeImgBedUtils;
import com.cool.shark.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

/**
 * @Name: BannerServiceImpl
 * @Author: 西风残叶
 * @Date: 2024/4/9 20:24
 * @Version: 1.0
 * @TODO: 轮播图的业务实现类
 */
@Slf4j
@Service
public class BannerServiceImpl implements BannerService {
    @Autowired
    private BannerMapper mapper;

    /**
     * 插入一个横幅广告到数据库或其他存储介质中。
     *
     * @param bannerDto 待插入的横幅广告对象，包含横幅广告的详细信息。
     */
    @Override
    public void insert(BannerDTO bannerDto) {
        log.debug("实现插入轮播图的业务,参数:{}", bannerDto);
        if (bannerDto == null) {
            String msg = "轮播图图片不能为空";
            throw new ServiceException(ServiceCode.ERR_BAD_REQUEST, msg);
        }
        log.debug("插入一个横幅广告到数据库或其他存储介质中。");
        Banner banner = new Banner();
        BeanUtils.copyProperties(bannerDto, banner);
        log.debug("开始插入,参数:{}", banner);
        int insert = mapper.insert(banner);
        if (insert != 1) {
            String msg = "插入失败";
            throw new ServiceException(ServiceCode.ERR_INSERT_FAILED, msg);
        }
        log.debug("插入成功");
    }

    /**
     * 从数据库或其他存储介质中获取所有Banner对象。
     *
     * @return 返回一个包含所有Banner对象的列表。
     */
    @Override
    public List<BannerVO> list() {
        log.info("开始处理查询轮播图列表业务");
        List<BannerVO> list = mapper.list();
        Iterator<BannerVO> iterator = list.iterator();
        while (iterator.hasNext()) {
            BannerVO next = iterator.next();
            log.info(next.getUrl());
        }
        return list;
    }

    /**
     * 使某个对象启用。
     *
     * @param id 对象的唯一标识符。
     */
    @Override
    public void setEnable(int id) {
        updateEnableById(id, 1);
    }

    /**
     * 使某个对象禁用。
     *
     * @param id 对象的唯一标识符。
     */
    @Override
    public void setDisable(int id) {
        updateEnableById(id, 0);
    }

    /**
     * 上传图片的方法。
     *
     * @param multipartFile 表示要上传的图片文件，是一个多部分文件对象。
     * @return 返回一个字符串，通常为上传成功后的图片URL或其他标识信息。
     * @throws IOException 如果在上传过程中发生IO异常。
     */
    @Override
    public String uploadImg(MultipartFile multipartFile) throws IOException {
        //根据文件名生成指定的请求url
        String originalFilename = multipartFile.getOriginalFilename();
        if (originalFilename == null) {
            return "文件不存在";
        }
        String targetURL = UploadGiteeImgBedUtils.
                createBannerUploadFileUrl(originalFilename);
        log.info("目标url：" + targetURL);
        //请求体封装
        Map<String, Object> uploadBodyMap = UploadGiteeImgBedUtils.
                getUploadBodyMap(multipartFile.getBytes());
        String JSONResult = HttpUtil.post(targetURL, uploadBodyMap);
        //解析响应JSON字符串
        JSONObject jsonObj = JSONUtil.parseObj(JSONResult);
        //请求失败
        if (jsonObj == null || jsonObj.getObj("commit") == null) {
            return "请求失败";
        }
        //请求成功：返回下载地址
        JSONObject content = JSONUtil.parseObj(jsonObj.getObj("content"));
        Object downloadUrl = content.getObj("download_url");
        log.info("下载地址：" + downloadUrl);
        return downloadUrl.toString();
    }



    /**
     * 根据指定的ID选择一个Banner对象。
     *
     * @param id 用于查询的Banner的唯一标识符。
     * @return 返回匹配的Banner对象，如果没有找到匹配的，则返回null。
     */
    @Override
    public BannerStandardVO select(int id) {
        log.info("开始处理查询轮播图详情业务,参数为:{}", id);
        if (id <= 0) {
            String msg = "查询轮播图详情失败!轮播图ID不能为空";
            throw new ServiceException(ServiceCode.ERR_BAD_REQUEST, msg);
        }
        BannerStandardVO select = mapper.select(id);
        if (select == null) {
            String msg = "查询轮播图详情失败!轮播图不存在";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, msg);
        }
        return select;
    }

    /**
     * 查询所有启用的轮播图信息
     *
     * @return 返回一个包含所有启用的轮播图信息的列表
     */
    @Override
    public List<BannerVO> listByEnable() {
        log.info("开始处理查询所有启用的轮播图信息业务");
        List<BannerVO> listByEnable = mapper.listByEnable();
        if (listByEnable != null) {
            return listByEnable;
        }
        return Collections.emptyList();
    }

    /**
     * 删除图片
     *
     * @param id 幻灯片对象，包含需要删除的图片的信息。
     *           该对象中应含有图片的标识符或其他必要的删除信息。
     */
    @Override
    public void delete(Integer id) {
        log.info("开始处理删除轮播图业务,参数为:{}", id);
        int delete = mapper.delete(id);
        if (delete != 1){
            String msg = "删除轮播图失败!";
            throw new ServiceException(ServiceCode.ERR_DELETE_FAILED, msg);
        }
        log.info("删除轮播图成功");
    }

    private void updateEnableById(int id, Integer enable) {
        String[] enableText = {"禁用", "启用"};
        log.info("开始处理[{}的业务],ID:{},目标状态:{}",
                enableText[enable], id, enableText[enable]);
        BannerStandardVO queryResult = mapper.select(id);
        if (queryResult == null) {
            String msg = enableText[enable] + "处理轮播图失败!" +
                    "尝试访问的轮播不存在!";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, msg);
        }
        if (queryResult.getEnable().equals(enable)) {
            String msg = enableText[enable] + "处理轮播图失败!" +
                    "轮播图已经处于" + enableText[enable] + "状态!";
            throw new ServiceException(ServiceCode.ERR_BAD_REQUEST, msg);
        }
        Banner banner = new Banner();
        banner.setId(id);
        banner.setEnable(enable);
        int update = mapper.update(banner);
        if (update != 1) {
            String msg = enableText[enable] + "处理轮播图失败,服务器忙!";
            throw new ServiceException(ServiceCode.ERR_UPDATE_FAILED, msg);
        }
    }
}
